﻿using UnityEngine;

namespace Miao
{
    /// <summary>
    /// 提供对Unity <see cref="GameObject"/> 的扩展支持
    /// </summary>
    public static class GameObjectExtension
    {
        /// <summary>
        /// 尝试添加组件.
        /// 如果组件已经存在于 <paramref name="self"/> 中, 则不添加
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="self"></param>
        /// <returns></returns>
        public static T TryAddComponent<T>(this GameObject self) where T : Component
        {
            T component = self.GetComponent<T>();
            if (!component) component = self.AddComponent<T>();
            return component;
        }
        /// <summary>
        /// 尝试添加组件到指定路径的子物体上.
        /// 如果组件已经存在, 则不添加
        /// </summary>
        public static T TryAddComponent<T>(this GameObject self, string path) where T : Component
        {
            Transform child = self.transform.Find(path);
            if (!child) throw new System.Exception($"{nameof(GameObjectExtension)}.{nameof(TryAddComponent)}: 无法在游戏对象 {self.name} 中找到子物体 {path}, 添加组件失败");
            T component = child.GetComponent<T>();
            if (!component) component = child.gameObject.AddComponent<T>();
            return component;
        }

        /// <summary>
        /// 添加组件到指定路径的子物体上
        /// </summary>
        public static T AddComponent<T>(this GameObject self, string path) where T : Component
        {
            Transform child = self.transform.Find(path);
            if (!child) throw new System.Exception($"{nameof(GameObjectExtension)}.{nameof(AddComponent)}: 无法在游戏对象 {self.name} 中找到子物体 {path}, 添加组件失败");
            return child.gameObject.AddComponent<T>();
        }
        public static T GetComponent<T>(this GameObject self, string path) where T : Component
        {
            return GetComponent<T>(self.transform, path);
        }
        public static T GetComponent<T>(this Transform self, string path) where T : Component
        {
            Transform child = self.Find(path);
            return child ? child.GetComponent<T>() : null;
        }
    }
}